/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.fina.manager;

import com.brain.come.dto.DocumentoVentaDto;
import com.brain.come.manager.DocumentoVentaManager;
import com.brain.core.common.ExportarExcelFinanzas;
import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.dto.ParametroDto;
import com.brain.core.manager.*;
import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.SessionMBean;
import com.brain.fina.dto.NotaDebitoDto;
import com.brain.fina.view.util.ConstantesFina;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.faces.model.SelectItem;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 * @author Greip Company
 * @since 09/01/2014
 * @version 1.0
 */
@Service
public class NotaDebitoManager extends ComunManager<NotaDebitoDto> implements Serializable {

    /**
     * Guarda las acciones del sistema en un archivo de texto plano
     *
     * @since 09/01/2014
     */
    private static Logger logger = Logger.getLogger(NotaDebitoManager.class);
    /**
     * Identificador de la entidad Finanzas
     *
     * @since 09/01/2014
     */
    private Long idEntidad = 273L;
    /**
     * Objeto que permite el acceso a la capa de datos
     *
     * @since 09/01/2014
     */
    @Resource
    private DAOGenerico<NotaDebitoDto> springHibernateDao;
    /**
     * Objeto que permite acceder a la clase utilitaria de configuración de la
     * aplicación
     *
     * @since 09/01/2014
     *
     */
    @Resource
    private ApplicationMBean applicationMBean;
    /**
     * Objeto que permite acceder a la clase utilitaria de datos
     *
     * @since 09/01/2014
     */
    @Resource
    private RecursosManager recursosManager;
    /**
     * Ruta que muestra la pagina principal de notas de Debito
     *
     * @since 09/01/2014
     */
    private final String url = "/pages/fina/notaDebito/notaDebito.xhtml";
    /**
     * Ruta que muestra la pagina de Listado de notas de debito
     *
     * @since 09/01/2014
     */
    private final String urlLista = "/pages/fina/notaDebito/listaNotasDebito.xhtml";

    /**
     * Metodo que obtiene todos los datos de la entidad
     *
     * @since 09/01/2014
     * @return retorna una lista con todos los datos de la entidad
     */
    public List<NotaDebitoDto> obtenerTodos() throws DAOException {
        return springHibernateDao.listarTodosDtos(NotaDebitoDto.class);
    }

    /**
     * Metodo que obtiene todos los datos de la entidad coincidentes con el
     * filtro
     *
     * @since 09/01/2014
     * @param filtros es el objeto de la Interfaz Map , que envía un map con 2
     * parámetros
     * @return retorna una lista con todos los datos de la entidad coincidentes
     * con el filtro
     */
    public List<NotaDebitoDto> obtenerConFiltro(Map<String, Object> filtros) throws DAOException {
        return springHibernateDao.obtenerDtosConFiltros(NotaDebitoDto.class, filtros);
    }

    /**
     * Metodo que obtiene todos los datos coincidentes con el filtro , además
     * permite manejar el orden de los datos
     *
     * @since 09/01/2014
     * @param filtros es el objeto de la Interfaz Map , que envía un mapa con 2
     * parámetros
     * @param orden es el objeto de la Interfaz Map , que envía un mapa con 2
     * parámetros
     * @return retorna una lista con todos los datos de la entidad coincidentes
     * con el filtro ordenado manualmente
     */
    public List<NotaDebitoDto> obtenerConFiltroConOrden(Map<String, Object> filtros, Map<String, String> orden) throws DAOException {
        return springHibernateDao.obtenerDtosConFiltrosConOrden(NotaDebitoDto.class, filtros, orden);
    }

    /**
     * Metodo que devuelve un Dto
     *
     * @since 09/01/2014
     * @param id identificador o codigo en la tabla a obtener
     * @return retorna un Dto lleno de datos en caso que encuentre coincidencias
     * con el parámetro enviado
     */
    public NotaDebitoDto obtenerPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(NotaDebitoDto.class, id);
    }

    /**
     * Metodo que devuelve una lista de valores de la Clase
     * FinanciamientoLetraDto
     *
     * @since 09/01/2014
     * @param notaDebitoDto objeto de la Clase NotaDebitoDto que se llenará
     * según la necesidad
     * @return retorna un Dto lleno de datos en caso que encuentre coincidencias
     * con el parámetro enviado
     */
    public List<NotaDebitoDto> obtenerNotasDebito(NotaDebitoDto notaDebitoDto) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        String query = "select e from NotaDebitoDto as e where e.documentoVentaDto.organizacionDto.id = ?  ";
        List<Object> listaParametros = new ArrayList<Object>();
        listaParametros.add(sessionMBean.getOrganizacionDto().getId());

        if (notaDebitoDto.getId() != null && !notaDebitoDto.getId().equals(0L)) {
            query += " and e.id = ?";
            listaParametros.add(notaDebitoDto.getId());
        } else {

            if (notaDebitoDto.getClienteDto() != null && notaDebitoDto.getClienteDto().getDescripcion() != null && notaDebitoDto.getClienteDto().getDescripcion().length() > 0) {
                query += " and upper(e.clienteDto.descripcion) like  " + "'%" + notaDebitoDto.getClienteDto().getDescripcion().toUpperCase() + "%'";
            }

            if (notaDebitoDto.getEstado() != null && !notaDebitoDto.getEstado().equals(ConstantesFina.ValoresConstantes.NOTA_CREDITO_COD_ESTADO_TODOS)) {
                query += " and e.estado = ?";
                listaParametros.add(notaDebitoDto.getEstado());
            }

            if (notaDebitoDto.getFechaInicio() != null && notaDebitoDto.getFechaFin() != null) {

                query += " and e.fechaCreacion between ? and ?";
                Calendar c = Calendar.getInstance();
                c.setTime(notaDebitoDto.getFechaInicio());
                c.set(Calendar.HOUR, 0);
                c.set(Calendar.MINUTE, 0);
                c.set(Calendar.SECOND, 0);
                listaParametros.add(c.getTime());
                c.setTime(notaDebitoDto.getFechaFin());
                c.set(Calendar.HOUR, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                listaParametros.add(c.getTime());
            }
        }
        query += " order by e.fechaCreacion desc, e.clienteDto.descripcion asc";


        return springHibernateDao.ejecutarQuery(query, listaParametros);
    }

    /**
     * Metodo que permite validar que la serie y el numero de una Nota de Debito
     * no se repitan
     *
     * @param notaDebitoDto dto que contiene los valores a validar (numeroy
     * serie)
     * @param accion objeto que indicará la acción DML en el cual se validarán
     * los valores
     * @since 09/01/2014
     * @return retorna el resultado de la validacion
     */
    public int validarSerieNumero(NotaDebitoDto notaDebitoDto, int accion) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        List<Object> listaParametros = new ArrayList<Object>();
        String query = "select count(e.id) from NotaDebitoDto as e where e.documentoVentaDto.id = ?  ";
        listaParametros.add(sessionMBean.getOrganizacionDto().getId());
        query += " and upper(e.numero) = '" + notaDebitoDto.getNumero().longValue() + "'";
        query += " and upper(e.serie) = '" + notaDebitoDto.getSerie().longValue() + "'";
        if (accion == applicationMBean.getEditar()) {
            query += " and e.id != ?";
            listaParametros.add(notaDebitoDto.getId());
        }
        return Integer.parseInt(springHibernateDao.ejecutarQueryGeneric(query, listaParametros).get(0).toString());
    }

    /**
     * Metodo que permite obtener un parametro ,enviando un valor Long como
     * parametro
     *
     * @param id id unica que se buscará en la clase ParametroDto
     * @since 09/01/2014
     * @return retorna un objeto de la clase parametroDto , o en caso que se
     * produzca un error retornará vacio
     */
    public ParametroDto obtenerParametroPorId(Long id) {
        ParametroManager parametroManager = (ParametroManager) WebServletContextListener.getApplicationContext().getBean("parametroManager");
        try {
            return parametroManager.obtenerPorId(id);
        } catch (DAOException ex) {
            logger.error(ex);
            return null;
        }
    }
 /**
     * Metodo que permite buscar documentos de venta a partir de un filtro
     *
     * @param filtro Nro de documento que se buscará
     * @since 09/01/2014
     * @return retorna una lista de documentos llena
     */
    public List<DocumentoVentaDto> listaDocumentosVentas(final String filtro) {
        DocumentoVentaManager dvManager = (DocumentoVentaManager) WebServletContextListener.getApplicationContext().getBean("documentoVentaManager");
        List<DocumentoVentaDto> listaDV = null;
        try {
            listaDV = dvManager.obtenerDocumentosVentaConfirmadosNotaDebito(filtro);
        } catch (DAOException ex) {
            logger.error(ex);
            listaDV = new ArrayList<DocumentoVentaDto>();
        }
        return listaDV;
    }

    /**
     * Metodo que permite llenar un arreglo de Items
     *
     * @since 09/01/2014
     * @return retorna un arreglo de items con codigo y descripcion
     */
    public SelectItem[] siTiposNotaDebitoTodos() {
        SelectItem[] si = new SelectItem[4];
        si[0] = new SelectItem(ConstantesFina.ValoresConstantes.NOTA_DEBITO_COD_ESTADO_TODOS, ConstantesFina.ValoresConstantes.NOTA_DEBITO_DESC_ESTADO_TODOS);
        si[1] = new SelectItem(ConstantesFina.ValoresConstantes.NOTA_DEBITO_COD_ESTADO_CONFIRMADO, ConstantesFina.ValoresConstantes.NOTA_DEBITO_DESC_ESTADO_CONFIRMADO);
        si[2] = new SelectItem(ConstantesFina.ValoresConstantes.NOTA_DEBITO_COD_ESTADO_ANULADO, ConstantesFina.ValoresConstantes.NOTA_DEBITO_DESC_ESTADO_ANULADO);
        si[3] = new SelectItem(ConstantesFina.ValoresConstantes.NOTA_DEBITO_COD_ESTADO_ELABORACION, ConstantesFina.ValoresConstantes.NOTA_DEBITO_DESC_ESTADO_ELABORACION);
        return si;
    }
/**
     * Metodo que permite exportar a excel informacion de la Tabla
     * NotaDebitoDto
     *
     * @since 09/01/2014
     * @param exp objeto de almacenará que campos se exportarán
     * @param selectedFLs arreglo de la clase NotaCredito donde se
     * almacenarán los valores a exportar
     */
    public void generarExcelSeleccionados(ExportarExcelFinanzas.NotaDebito exp, NotaDebitoDto[] selectedNDs) {
        StringBuilder strCabecera = this.obtenerCabeceraExcel(exp);
        List<NotaDebitoDto> lst = Arrays.asList(selectedNDs);
        List lstCuerpo = this.obtenerCuerpoExcel(exp, lst);
        String nombreArchivo = "NOTAS_DEBITO_" + UtilCore.Fecha.obtenerFechaHoraActual().replace(':', '_') + ".xls";
        this.recursosManager.generarExcel(strCabecera.toString(), lstCuerpo, nombreArchivo);
        this.recursosManager.viewArchivo(nombreArchivo);
    }
 /**
     * Metodo que permite exportar a excel informacion de la Tabla
     * NotaDebitoDto
     *
     * @since 09/01/2014
     * @param exp objeto de almacenará que campos se exportarán
     * @param selectedFLs lista de la clase NotaDebitoDto donde se
     * almacenarán los valores a exportar
     */
    public void generarExcelPorTabla(ExportarExcelFinanzas.NotaDebito exp, List<NotaDebitoDto> lstND) {
        StringBuilder strCabecera = this.obtenerCabeceraExcel(exp);
        List lstCuerpo = this.obtenerCuerpoExcel(exp, lstND);
        String nombreArchivo = "NOTAS_DEBITO_" + UtilCore.Fecha.obtenerFechaHoraActual().replace(':', '_') + ".xls";
        this.recursosManager.generarExcel(strCabecera.toString(), lstCuerpo, nombreArchivo);
        this.recursosManager.viewArchivo(nombreArchivo);
    }
    /**
     * Metodo que , crea el cuerpo del documento de excel
     *
     * @since 09/01/2014
     * @param exp objeto que contiene los valores seleccionados
     * @param lst lista de la clase NotaDebitoDto que contiene
     * los valores a exportar
     * @return return lstFilas devuelve una lista con los datos seteados
     */

    private List obtenerCuerpoExcel(ExportarExcelFinanzas.NotaDebito exp, List<NotaDebitoDto> lst) {
        StringBuilder strCuerpo;
        List lstFilas = new ArrayList();
        for (NotaDebitoDto x : lst) {
            strCuerpo = new StringBuilder();
            if (exp.getId()) {
                strCuerpo.append(x.getId()).append("|");
            }
            if (exp.getEstado()) {
                if (x.getEstado() != null) {
                    strCuerpo.append(x.getEstadoTexto()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getDocumentoVenta()) {
                if (x.getDocumentoVentaDto() != null) {
                    strCuerpo.append(x.getDocumentoVentaDto().getId()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getMotivo()) {
                if (x.getMotivoDto() != null) {
                    strCuerpo.append(x.getMotivoDto().getDescripcion()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getMotivoAdicional()) {
                if (x.getMotivoAdicional() != null) {
                    strCuerpo.append(x.getMotivoAdicional()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getSerie()) {
                if (x.getSerie() != null) {
                    strCuerpo.append(x.getSerie()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getNumero()) {
                if (x.getNumero() != null) {
                    strCuerpo.append(x.getNumero()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getCliente()) {
                if (x.getClienteDto() != null) {
                    strCuerpo.append(x.getClienteDto().getDescripcion()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getSubTotal()) {
                if (x.getSubTotal() != null) {
                    strCuerpo.append(x.getSubTotal()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getImpuestoVenta()) {
                if (x.getImpuestoVenta() != null) {
                    strCuerpo.append(x.getImpuestoVenta()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getMontoImpuestoVenta()) {
                if (x.getMontoImpuestoVenta() != null) {
                    strCuerpo.append(x.getMontoImpuestoVenta()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getMoneda()) {
                if (x.getMonedaDto() != null) {
                    strCuerpo.append(x.getMonedaDto().getDescripcion()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getTotal()) {
                if (x.getTotal() != null) {
                    strCuerpo.append(x.getTotal()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getUsuarioCreacion()) {
                if (x.getUsuarioCreacionDto() != null) {
                    strCuerpo.append(x.getUsuarioCreacionDto().getDescripcion()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getFechaCreacion()) {
                if (x.getFechaCreacion() != null) {
                    strCuerpo.append(x.getFechaCreacion()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getTerminalCreacion()) {
                if (x.getTerminalCreacion() != null) {
                    strCuerpo.append(x.getTerminalCreacion()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getComentario()) {
                if (x.getComentario() != null) {
                    strCuerpo.append(x.getComentario()).append("|");
                } else {
                    strCuerpo.append("-").append("|");
                }
            }
            lstFilas.add(strCuerpo.toString());
        }
        return lstFilas;
    }
  /**
     * Metodo que crea la cabezera del documento de excel
     *
     * @since 09/01/2014
     * @param exp objeto que indica que columnas del documento serán rellenadas
     * @return devuelve una cadena construida respectivamente
     */
    private StringBuilder obtenerCabeceraExcel(ExportarExcelFinanzas.NotaDebito exp) {
        StringBuilder strCabecera = new StringBuilder();
        if (exp.getId()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("general.label.id")).append("|");
        }
        if (exp.getEstado()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("general.label.estado")).append("|");
        }
        if (exp.getDocumentoVenta()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.documento.venta")).append("|");
        }
        if (exp.getMotivo()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.motivo")).append("|");
        }
        if (exp.getMotivoAdicional()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.motivo.adicional")).append("|");
        }
        if (exp.getSerie()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.serie")).append("|");
        }
        if (exp.getNumero()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.numero")).append("|");
        }
        if (exp.getCliente()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.cliente")).append("|");
        }
        if (exp.getSubTotal()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.sub.total")).append("|");
        }
        if (exp.getImpuestoVenta()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.impuesto.venta")).append("|");
        }
        if (exp.getMontoImpuestoVenta()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.monto.impuesto.venta")).append("|");
        }
        if (exp.getMoneda()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.moneda")).append("|");
        }
        if (exp.getTotal()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.total")).append("|");
        }
        if (exp.getUsuarioCreacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.usuario.creacion")).append("|");
        }
        if (exp.getFechaCreacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.fecha.creacion")).append("|");
        }
        if (exp.getTerminalCreacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.terminal.creacion")).append("|");
        }
        if (exp.getComentario()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("nota.debito.comentario")).append("|");
        }

        return strCabecera;
    }
 /**
     * Metodo que indica que campos a exportar están seleccionados
     *
     * @since 09/01/2014
     * @param flag es el valor booleano
     * @return devuelve una clase tipo ExportarExcelFinanzas.NotaDebito
     * indicando que valores se exportarán
     */
    public ExportarExcelFinanzas.NotaDebito onChangeChekExcel(Boolean flag) {
        return new ExportarExcelFinanzas.NotaDebito(flag);
    }

    public String getUrl() {
        return url;
    }

    public String getUrlLista() {
        return urlLista;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        NotaDebitoManager.logger = logger;
    }

    public Long getIdEntidad() {
        return idEntidad;
    }

    public void setIdEntidad(Long idEntidad) {
        this.idEntidad = idEntidad;
    }

    public DAOGenerico<NotaDebitoDto> getSpringHibernateDao() {
        return springHibernateDao;
    }

    public void setSpringHibernateDao(DAOGenerico<NotaDebitoDto> springHibernateDao) {
        this.springHibernateDao = springHibernateDao;
    }

    public ApplicationMBean getApplicationMBean() {
        return applicationMBean;
    }

    public void setApplicationMBean(ApplicationMBean applicationMBean) {
        this.applicationMBean = applicationMBean;
    }
}